/*-------------------------------------------------------------------------
 *
 * pg_crc32c_sse42.c
 *	  使用Intel SSE 4.2指令计算CRC-32C校验和。
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *	  src/port/pg_crc32c_sse42.c
 *
 *-------------------------------------------------------------------------
 */
#include "c.h"

#include <nmmintrin.h>

#include "port/pg_crc32c.h"

pg_attribute_no_sanitize_alignment()
pg_crc32c pg_comp_crc32c_sse42(pg_crc32c fc_crc, const void *fc_data, size_t fc_len)
{
	const unsigned char *fc_p = fc_data;
	const unsigned char *fc_pend = fc_p + fc_len;

	/*
	 * 一次处理八个字节的数据。
	 *
	 * 注意：我们在这里进行非对齐访问。Intel架构允许这样做，
	 * 性能测试没有显示出对齐起始地址会带来任何性能提升。
	 */
#ifdef __x86_64__
	while (fc_p + 8 <= fc_pend)
	{
		fc_crc = (uint32) _mm_crc32_u64(fc_crc, *((const uint64 *) fc_p));
		fc_p += 8;
	}

	/* 如果有，则处理剩余的完整四个字节 */
	if (fc_p + 4 <= fc_pend)
	{
		fc_crc = _mm_crc32_u32(fc_crc, *((const unsigned int *) fc_p));
		fc_p += 4;
	}
#else

	/*
	 * 一次处理四个字节。 （在32位x86架构上没有八字节指令）。
	 */
	while (fc_p + 4 <= fc_pend)
	{
		fc_crc = _mm_crc32_u32(fc_crc, *((const unsigned int *) fc_p));
		fc_p += 4;
	}
#endif							/* __x86_64__ */

	/* 一次处理任意剩余的字节。 */
	while (fc_p < fc_pend)
	{
		fc_crc = _mm_crc32_u8(fc_crc, *fc_p);
		fc_p++;
	}

	return fc_crc;
}
